using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.UI;


/// <summary>
/// 角色控制器
/// </summary>
public class PlayerController : MonoBehaviour
{
    public CharacterController characterController;
    public Vector3 moveDirction;//设置人物移动方向 
    private AudioSource audioSource;

    [Header("玩家数值")]
    public float Speed;
    [Tooltip("行走速度")] public float walkSpeed;
    [Tooltip("奔跑速度")] public float runSpeed;
    [Tooltip("下蹲行走速度")] public float crouchSpeed;
    [Tooltip("玩家生命值")] public float playerHealth;


    [Tooltip("跳跃的力")] public float jumpForce;
    [Tooltip("下落的力")] public float fallForce;
    [Tooltip("下蹲时候的玩家高度")] public float crouchHeight;
    [Tooltip("站立时的玩家高度")] public float standHeight;


    [Header("键位设置")]
    [Tooltip("奔跑按键")] public KeyCode runInputName = KeyCode.LeftShift;
    [Tooltip("跳跃按键")] public KeyCode jumpInputName = KeyCode.Space;
    [Tooltip("下蹲按键")] public KeyCode crouchInputName = KeyCode.LeftControl;

    [Header("玩家属性判断")]
    public MovementState state;
    private CollisionFlags collisionFlags;
    public bool isWalk;//判断玩家是否行走
    public bool isRun;//判断玩家是否奔跑
    public bool isJump;//判断玩家是否跳跃
    public bool isGround;//判断玩家是在地面
    public bool isCanCrouch;//判断玩家是否可以下蹲
    public bool isCrouching;//判断玩家是否正在下蹲
    public bool playerisDead;//判断玩家是否死亡
    public bool isDamage;//判断玩家是否受伤


    public LayerMask crouchLayerMask;
    public Text playerHealthUI;
    public Image hurtimage;//玩家血雾效果
    private Color flashColor = new Color(1f,0f,0f,1f);
    private Color clearColor = Color.clear;

    [Header("音效")]
    [Tooltip("行走音效")] public AudioClip walkSound;
    [Tooltip("奔跑音效")] public AudioClip runSound;

    private Inventory inventory;

    // Start is called before the first frame update
    void Start()
    {
        playerHealth = 100f;
        audioSource = GetComponent<AudioSource>();
        characterController = GetComponent<CharacterController>();
        walkSpeed = 4f;
        runSpeed = 6f;
        crouchSpeed = 2f;
        jumpForce = 0f;
        fallForce = 10f;
        crouchHeight = 1f;
        standHeight = characterController.height;
        inventory=GetComponentInChildren<Inventory>();
        playerHealthUI.text = "生命值：" + playerHealth;
    }

    // Update is called once per frame
    void Update()
    {
        //玩家受到伤害，屏幕产生红色渐变
        if(isDamage)
        {
            hurtimage.color = flashColor;
        }
        else
        {
            hurtimage.color = Color.Lerp(hurtimage.color,clearColor,Time.deltaTime*5);
        }
        isDamage = false;
        if(playerisDead)
        {
            return;
        }

        CanCrouch();
        if(Input.GetKey(crouchInputName))
        {
            Crouch(true);
        }
        else
        {
            Crouch(false);
        }
        Moving();
        Jump();
        PlayerFootSoundSet();
    }

    /// <summary>
    /// 人物移动
    /// </summary>
    public void Moving()
    {
        //移动急停GetAxisRaw，不急停GetAxis
        float h = Input.GetAxisRaw("Horizontal");
        float v = Input.GetAxisRaw("Vertical");

        bool hasMovement = Mathf.Abs(h) > 0 || Mathf.Abs(v) > 0;

        isRun = Input.GetKey(runInputName) && hasMovement;
        isWalk = hasMovement;
        if (isRun && isGround && isCanCrouch && !isCrouching)
        {
            state = MovementState.running;
            Speed = runSpeed;
        }
        else if (isGround)//正常行走
        {
            state = MovementState.walking;
            Speed = walkSpeed;
            //下蹲行走
            if(isCrouching)
            {
                state = MovementState.crouching;
                Speed = crouchSpeed;
            }
        }
        //如果同时按下下蹲和奔跑，人物应该是下蹲速度而不是奔跑速度
        if(isRun&&isCrouching)
        {
            state = MovementState.crouching;
            Speed = crouchSpeed;
        }


        //设置人物移动方向,normalized将速度规范化防止斜方向速度变大
        moveDirction = (transform.right * h + transform.forward * v).normalized;
        characterController.Move(moveDirction * Speed * Time.deltaTime);//人物移动
    }

    /// <summary>
    /// 跳跃
    /// </summary>
    public void Jump()
    {
        if (!isCanCrouch)
        {
            return;
        }
        isJump = Input.GetKeyDown(jumpInputName);
        //判断玩家在地面并且按下跳跃键位才能跳跃
        if (isJump && isGround)
        {
            isGround = false;
            jumpForce = 5f;//设置跳跃力度
        }
        else if(!isJump && isGround)
        {
            isGround = false;
        }

        //此时跳起来了，并且不再地面上
        if (!isGround)
        {
            jumpForce = jumpForce - fallForce * Time.deltaTime;//每秒跳跃力累减，使其进行下落
            Vector3 jump = new Vector3(0, jumpForce * Time.deltaTime, 0);//将跳跃力转换为V3坐标
            collisionFlags = characterController.Move(jump);//调用角色控制器移动方法，向上移动模拟跳跃

            /*判断玩家在地面上
            CollisionFlags:characterController内置的碰撞位置标识号
            CollisionFlags.Below-->在地面上
            */
            if (collisionFlags == CollisionFlags.Below)
            {
                isGround = true;
                jumpForce = -2f;
            }
        }
    }
    /// <summary>
    /// 判断人物是否可以下蹲
    /// isCanCrouch==true 可以下蹲，此时人物站立
    /// isCanCrouch==false 不可以下蹲，人物头顶有碰撞
    /// </summary>
    public void CanCrouch()
    {
        //获取人物头顶的高度V3位置
        Vector3 sphereLocation = transform.position + Vector3.up * standHeight;
        //判断头顶是否有物体，判断是否可以下蹲
        isCanCrouch=(Physics.OverlapSphere(sphereLocation, characterController.radius, crouchLayerMask).Length)==0;
        
    }

    public void Crouch(bool newCrounching)
    {
        if(!isCanCrouch)
        {
            return;
        }
        isCrouching = newCrounching;
        characterController.height = isCrouching ? crouchHeight : standHeight;//根据下蹲状态设置下蹲时的高度和站立高度
        characterController.center = characterController.height / 2f * Vector3.up;//将角色的中心位置Y，从头顶往下减少一半的高度
    }

    /// <summary>
    /// 人物移动音效
    /// </summary>
    public void PlayerFootSoundSet()
    {
        if(isGround && moveDirction.sqrMagnitude > 0)
        {
            audioSource.clip = isRun ? runSound : walkSound;
            if(!audioSource.isPlaying)
            {
                //播放行走或者奔跑的音效
                audioSource.Play();
            }
        }
        else
        {
            if (audioSource.isPlaying)
            {
                //暂停播放行走或者奔跑的音效
                audioSource.Pause();
            }
        }
        if(isCrouching)
        {
            if (audioSource.isPlaying)
            {
                //暂停播放行走或者奔跑的音效
                audioSource.Pause();
            }
        }
    }

    /// <summary>
    /// 拾取武器
    /// </summary>
    public void PickUpWeapon(int item,GameObject weapon)
    {
        //拾取武器后，在武器库里添加，否则补充备弹
        if(inventory.weapons.Contains(weapon))
        {
            weapon.GetComponent<Weapon_AutomaticGun>().bulletLeft = weapon.GetComponent<Weapon_AutomaticGun>().bulletMag * 5;
            weapon.GetComponent<Weapon_AutomaticGun>().UpdateAmmoUI();
            return;
        }
        else
        {
            inventory.AddWeapon(weapon);
        }
    }

    /// <summary>
    /// 玩家生命值
    /// </summary>
    /// <param name="damage">接受到的伤害</param>
    public void PlayerHealth(float damage)
    {
        playerHealth -= damage;
        isDamage = true;
        playerHealthUI.text = "生命值："+ playerHealth;
        if (playerHealth <= 0)
        {
            playerisDead = true;
            playerHealthUI.text = "玩家死亡";
            Time.timeScale = 0;//游戏暂停
        }
    }

    public enum MovementState
    {
        walking,
        running,
        crouching,
    }
}
